package com.xinzhidi.web.task;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xinzhidi.common.constant.AgreementConstants;
import com.xinzhidi.web.dtuusr.domain.DtuUsr;
import com.xinzhidi.web.dtuusr.service.DtuUsrService;
import com.xinzhidi.web.equipment.domain.Equipment;
import com.xinzhidi.web.equipment.service.EquipmentService;
import com.xinzhidi.web.equipmentAlarm.domain.EquipmentAlarm;
import com.xinzhidi.web.equipmentAlarm.service.EquipmentAlarmService;
import com.xinzhidi.web.netty.entity.vo.DeviceInstructionStatusVo;
import com.xinzhidi.web.netty.service.DeviceInstructionService;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 定时检查dtu是否在线
 *
 * @author cx
 */
@Component("checkDtuOnlineTask")
public class CheckDtuOnlineTask {

    @Autowired
    private DtuUsrService dtuUsrService;

    @Autowired
    private EquipmentService equipmentService;

    @Autowired
    private DeviceInstructionService deviceInstructionService;

    @Autowired
    private EquipmentAlarmService alarmService;

    public void ryNoParams() {
        this.onlineTask();
    }

    private String onlineTask() {
        checkEquipmentStatus();
        List<DtuUsr> dtuUsrList = dtuUsrService.getOnOffList();
        if (CollectionUtils.isEmpty(dtuUsrList)) {
            return null;
        }
        //设置dtuUsrList的状态为不在线
        dtuUsrList.forEach(dtuUsr -> dtuUsr.setStatus(1));
        dtuUsrService.updateBatchById(dtuUsrList);

        //设置dtu下的设备状态为离线
        UpdateWrapper<Equipment> equipmentWrapper = new UpdateWrapper<>();
        equipmentWrapper.set("status", 2)
                .in("dtu_id", dtuUsrList.stream().map(DtuUsr::getId).collect(Collectors.toList()));
        equipmentService.update(equipmentWrapper);
        EquipmentAlarm equipmentAlarm;
        List<EquipmentAlarm> alarmList = Lists.newArrayList();
        List<EquipmentAlarm> existList = alarmService.list(Wrappers.<EquipmentAlarm>lambdaQuery()
                .in(EquipmentAlarm::getEquipmentId, dtuUsrList.stream().map(DtuUsr::getId).collect(Collectors.toList()))
                .eq(EquipmentAlarm::getAlarmSettingId, 0)
                .eq(EquipmentAlarm::getStatus, 0)
        );
        List<Long> existIdList = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(existList)) {
            existIdList = existList.stream().distinct().map(EquipmentAlarm::getEquipmentId).collect(Collectors.toList());
        }
        // 新增dtu异常
        for (DtuUsr dtuUsr : dtuUsrList) {
            if (!CollectionUtils.isEmpty(existIdList) && existIdList.contains(dtuUsr.getId())) {
                continue;
            }
            equipmentAlarm = new EquipmentAlarm();
            equipmentAlarm.setPlotId(0L);
            equipmentAlarm.setBuildId(0L);
            equipmentAlarm.setUnitId(0L);
            equipmentAlarm.setHouseholdId(0L);
            equipmentAlarm.setEquipmentId(dtuUsr.getId());
            equipmentAlarm.setAlarmSettingId(0L);
            equipmentAlarm.setHideOrPush(1);
            equipmentAlarm.setRemark("DTU" + dtuUsr.getName() + "【" + dtuUsr.getPort() + "】" + "通讯异常");
            alarmList.add(equipmentAlarm);
        }
        alarmService.saveBatch(alarmList);
        return null;
    }

    private void checkEquipmentStatus() {
        //获取每个设备最新指令的回复数据
        List<DeviceInstructionStatusVo> statusList = deviceInstructionService.getLastStatus();
        if (CollectionUtils.isEmpty(statusList)) {
            return;
        }
        //回复正常的指令
        List<Long> normalList = Lists.newArrayList();
        //回复失败的指令
        List<Long> abnormalList = Lists.newArrayList();
        for (DeviceInstructionStatusVo statusVo : statusList) {
            if (statusVo.getStatus().equals(AgreementConstants.InstructSendingState.SEND_FAILURE)) {
                abnormalList.add(statusVo.getEquipmentId());
            } else if (statusVo.getStatus().equals(AgreementConstants.InstructSendingState.RETURN_TO_NORMAL)) {
                normalList.add(statusVo.getEquipmentId());
            }
        }
        LambdaUpdateWrapper<Equipment> updateWrapper = new LambdaUpdateWrapper();
        if (!CollectionUtils.isEmpty(normalList)) {
            updateWrapper.set(Equipment::getStatus, 1).in(Equipment::getId, normalList);
            equipmentService.update(updateWrapper);
        }
        if (!CollectionUtils.isEmpty(abnormalList)) {
            updateWrapper.clear();
            updateWrapper.set(Equipment::getStatus, 2).in(Equipment::getId, abnormalList);
            equipmentService.update(updateWrapper);
        }
    }
}
